
package com.myt.matp.utils;

import java.lang.StringBuffer;


/**
 * Describe class <code>Edit</code> here.
 *
 * @author <a href="mailto:emadridm@gmail.com">Enrique Madrid</a>
 * @version 1.0
 */
public class Edit {

    public static final char CHAR_NEWLINE = '\n';
    public static final char CHAR_BRKLINE = '\r';
    public static final char CHAR_NULL = '�';

    private static final int INIT_SIZE = 160;

    private boolean m_Modified = false;

    private StringBuffer m_Buffer;

    private int m_Point = 0;

    public Edit(int size) {
	m_Buffer = new StringBuffer(size);
    }

    public Edit() {
	this(INIT_SIZE);
    }

    public final void setPoint(int location) {
	if ((location >= 0) &&
	    (location <= end())) {
	    m_Point = location;
	}
    }

    public final int getPoint() {
	return m_Point;
    }

    public final void movePoint(int count) {
	m_Point += count;
	if (m_Point < 0) {
	    m_Point = 0;
	}
	else if (m_Point > end()) {
	    m_Point = end();
	}
    }

    public final int start() {
	return 0;
    }

    public final int end() {
	return m_Buffer.length();
    }

    public final char getChar() {
	char ret = CHAR_NULL;
	if (m_Point < end()) {
	    ret = m_Buffer.charAt(m_Point);
	}
	return ret;
    }

    public final int getNumChars() {
	return end();
    }

    public final void setModified() {
	m_Modified = true;
    }

    public final boolean getModified() {
	return m_Modified;
    }

    public final void putChar(char c) {
	if (atEnd()) {
	    m_Buffer.append(c);
	}
	else {
	    m_Buffer.insert(m_Point, c);
	}
    }

    public final void insertChar(char c) {
	putChar(c);
	movePoint(1);
    }

    public final void replaceChar(char c) {
	if (!atEnd()) {
	    m_Buffer.setCharAt(getPoint(), c);
	}
    }

    public final void setString(String s) {
	m_Buffer.setLength(0);
	m_Buffer.append(s);
    }

    public final void delete(int count) {
	if (count < 0) {
	    movePoint(count);
	    count = -count;
	}
	m_Buffer.delete(getPoint(), Math.min(end(), getPoint() + count));
    }

    public final boolean atEnd() {
	return (getPoint() == end());
    }

    public final boolean atStart() {
	return (getPoint() == start());
    }

    public final boolean isCharEqualTo(char c) {
	return (getChar() == c);
    }

    public boolean isPointOnBreakLine() {
	return (isCharEqualTo(Edit.CHAR_NEWLINE) || 
		isCharEqualTo(Edit.CHAR_BRKLINE));
    }

    public final boolean isPointAtMark(int location) {
	return (getPoint() == location);
    }

    public final void findFirstInBackward(char c) {
	while (!isCharEqualTo(c) && !atStart()) {
	    movePoint(-1);
	}
    }

    public void findFirstInBackwardBreakLine() {
	do {
	    if (isPointOnBreakLine()) {
		break;
	    }
	    movePoint(-1);
	} while (!atStart());
    }

    public void findFirstInForewardBreakLine() {
	do {
	    if (isPointOnBreakLine()) {
		break;
	    }
	    movePoint(1);
	} while (!atEnd());
    }

    public final void setPointAtStart() {
	setPoint(start());
    }

    public final void setPointAtEnd() {
	setPoint(end());
    }

    /**
     * Describe <code>findFirstInForeward</code> method here.
     *
     * Searches the buffer starting from the point for the first
     * occurence of any character in the supplied string. Thus, 
     * Find_First_In_Forward("0123456789") would leave the point 
     * before the first digit found after the point. Unlike the 
     * Search_* routines, this routine leaves the point at the 
     * end of the buffer if no characters in the string are found. 
     * A typical use of the Find_* routines is this sequence, 
     * which skips over the first number after the point:
     *
     * Find_First_In_Forward("0123456789");
     * Find_First_Not_In_Forward("0123456789");
     *
     * @param chars a <code>char</code> value
     */
    public final void findFirstInForeward(char chars[]) {
	while (!atEnd()) {
	    if (Util.findChar(getChar(), chars) > 0) {
		break;
	    }
	    movePoint(1);
	}
    }

    /**
     * Describe <code>findFirstInBackward</code> method here.
     *
     * works in the obvious way.
     *
     * @param chars a <code>char</code> value
     */
    public final void findFirstInBackward(char chars[]) {
	while (!atStart()) {
	    if (Util.findChar(getChar(), chars) > 0) {
		break;
	    }
	    movePoint(-1);
	}
    }
}